# Misc Ammo used for Scarabs and Interceptors.
# This spell helps create those units on their producing unit (reaver, carrier)
from CvPythonExtensions import *

import GerikSpells
from GerikSpells import GerikSpellBase
from GSGroupPolicies import GSAny as GSGroup
from GSHandlerPolicies import GSImmediateNoTarget as GSHandler
from GSResultsPolicies import GSMissionNoTarget as GSResults

import GerikSpellsUtils

from CivcraftSCUtils import showNotEnoughMineralsMsg
from CivcraftSCUtils import isHallucination

gc = CyGlobalContext()
localtext = CyTranslator()

#
# Build spell base
#
class MiscAmmoBuildBase(GerikSpellBase, GSGroup, GSHandler, GSResults):
    def __init__(self):
        GerikSpellBase.__init__(self)
        GSGroup.__init__(self)
        GSHandler.__init__(self)
        GSResults.__init__(self)

        self.m_szNotValidText = localtext.getText( "TXT_KEY_MISC_AMMO_CAPCITY", () )

        peAmmoUnitClassType = lambda eUnit: gc.getUnitInfo(eUnit).getMiscAmmoUnitClassType();
	self.peAmmoUnitType = lambda iPlayer, eUnit: gc.getCivilizationInfo(gc.getPlayer(iPlayer).getCivilizationType()).getCivilizationUnits(peAmmoUnitClassType(eUnit))
        self.piAmmoCost = lambda eUnit: gc.getUnitInfo(eUnit).getMineralCost()

    def canUnitCast(self, pCastingUnit, pPlot, bVisible):
        # Misc ammo producers only
        if not gc.getUnitInfo(pCastingUnit.getUnitType()).isMiscAmmoBuildable():
            return False

        if isHallucination(pCastingUnit):
            return False

        if bVisible:
            return True

        # Check if they've reached their capacity
        if (pCastingUnit.getMiscAmmo() + pCastingUnit.getMiscAmmoQueueLength()) == pCastingUnit.getMaxMiscAmmo():
            return False

        return True

    def startSpellResults(self, pCastingGroup, pTarget):
        bShowNotEnoughMinerals = False
        
        iPlayer = pCastingGroup.getOwner()
        pPlayer = gc.getPlayer(iPlayer)
        
        for pLoopUnit in pCastingGroup.getUnits():
            if self.canUnitCast(pLoopUnit, pLoopUnit.plot(), False):
                eAmmoType = self.peAmmoUnitType(iPlayer, pLoopUnit.getUnitType())
                iAmmoCost = self.piAmmoCost(eAmmoType)
                
                if pPlayer.getGold() >= iAmmoCost:
                    pPlayer.changeGold(-1 * iAmmoCost)
                    pLoopUnit.changeMiscAmmoQueueLength(1)
                else:
                    bShowNotEnoughMinerals = True

        if bShowNotEnoughMinerals:
            showNotEnoughMineralsMsg(iPlayer)

class BuildScarab(MiscAmmoBuildBase):
    def __init__(self):
        MiscAmmoBuildBase.__init__(self)
        self.eUnitType = gc.getInfoTypeForString("UNIT_REAVER")

    def getHelpText(self, pGroup, pPlot):
        bValid = self.canGroupCast(pGroup, pPlot, False)
        if not bValid:
            return self.m_szNotValidText
        else:
            eAmmoType = self.peAmmoUnitType(gc.getGame().getActivePlayer(), self.eUnitType)
            iAmmoCost = self.piAmmoCost(eAmmoType)

            szValidText = "%d %s\n" % (iAmmoCost, localtext.getText("TXT_KEY_MINERALS_ICON", ()))
            szValidText += gc.getSpellInfo(self.getSpellNumber()).getHelp()
            return szValidText

    def canUnitCast(self, pCastingUnit, pPlot, bVisible):
        # Reavers only
        if not self.eUnitType == pCastingUnit.getUnitType():
            return False

        if not MiscAmmoBuildBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        if bVisible:
            return True

        if not MiscAmmoBuildBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        return True

class BuildInterceptor(MiscAmmoBuildBase):
    def __init__(self):
        MiscAmmoBuildBase.__init__(self)
        self.eUnitType = gc.getInfoTypeForString("UNIT_CARRIER")

    def getHelpText(self, pGroup, pPlot):
        bValid = self.canGroupCast(pGroup, pPlot, False)
        if not bValid:
            return self.m_szNotValidText
        else:
            eAmmoType = self.peAmmoUnitType(gc.getGame().getActivePlayer(), self.eUnitType)
            iAmmoCost = self.piAmmoCost(eAmmoType)

            szValidText = "%d %s\n" % (iAmmoCost, localtext.getText("TXT_KEY_MINERALS_ICON", ()))
            szValidText += gc.getSpellInfo(self.getSpellNumber()).getHelp()
            return szValidText

    def canUnitCast(self, pCastingUnit, pPlot, bVisible):
        # Carrier only
        if not self.eUnitType == pCastingUnit.getUnitType():
            return False

        if not MiscAmmoBuildBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        if bVisible:
            return True

        if not MiscAmmoBuildBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        return True


#
# Cancel spell base
#
class MiscAmmoCancelBase(GerikSpellBase, GSGroup, GSHandler, GSResults):
    def __init__(self):
        GerikSpellBase.__init__(self)
        GSGroup.__init__(self)
        GSHandler.__init__(self)
        GSResults.__init__(self)

        peAmmoUnitClassType = lambda eUnit: gc.getUnitInfo(eUnit).getMiscAmmoUnitClassType();
	self.peAmmoUnitType = lambda iPlayer, eUnit: gc.getCivilizationInfo(gc.getPlayer(iPlayer).getCivilizationType()).getCivilizationUnits(peAmmoUnitClassType(eUnit))
        self.piAmmoCost = lambda eUnit: gc.getUnitInfo(eUnit).getMineralCost()

    def canUnitCast(self, pCastingUnit, pPlot, bVisible):
        # Misc ammo producers only
        if not gc.getUnitInfo(pCastingUnit.getUnitType()).isMiscAmmoBuildable():
            return False

        if isHallucination(pCastingUnit):
            return False

        # Check if they have an item they can remove
        if not pCastingUnit.getMiscAmmoQueueLength() > 0:
            return False

        if bVisible:
            return True

        return True

    def startSpellResults(self, pCastingGroup, pTarget):
        
        iPlayer = pCastingGroup.getOwner()
        pPlayer = gc.getPlayer(iPlayer)
        
        for pLoopUnit in pCastingGroup.getUnits():
            if self.canUnitCast(pLoopUnit, pLoopUnit.plot(), False):
                eAmmoType = self.peAmmoUnitType(iPlayer, pLoopUnit.getUnitType())
                iAmmoCost = self.piAmmoCost(eAmmoType)
                
                pPlayer.changeGold(iAmmoCost)
                pLoopUnit.changeMiscAmmoQueueLength(-1)


        
class CancelScarab(MiscAmmoCancelBase):
    def __init__(self):
        MiscAmmoCancelBase.__init__(self)
        self.eUnitType = gc.getInfoTypeForString("UNIT_REAVER")

    def canUnitCast(self, pCastingUnit, pPlot, bVisible):
        # Reavers only
        if not self.eUnitType == pCastingUnit.getUnitType():
            return False

        if not MiscAmmoCancelBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        if bVisible:
            return True

        if not MiscAmmoCancelBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        return True

class CancelInterceptor(MiscAmmoCancelBase):
    def __init__(self):
        MiscAmmoCancelBase.__init__(self)
        self.eUnitType = gc.getInfoTypeForString("UNIT_CARRIER")

    def canUnitCast(self, pCastingUnit, pPlot, bVisible):
        # Carrier only
        if not self.eUnitType == pCastingUnit.getUnitType():
            return False

        if not MiscAmmoCancelBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        if bVisible:
            return True

        if not MiscAmmoCancelBase.canUnitCast(self, pCastingUnit, pPlot, bVisible):
            return False

        return True
                        
            
        
            
            
